import java.util.*;

import static java.util.Collections.swap;

public class AdvancedApplication {
    public static void main(String[] args) {
        // 1. 泛型类演示
        //genericClassDemo();

        // 2. 泛型方法演示
        //genericMethodDemo();

        // 3. 通配符演示
        //wildcardDemo();

        // 4. 类型擦除演示
        //typeErasureDemo();

        // 5. 泛型最佳实践
        bestPracticesDemo();
    }

    /**
     * 泛型类演示
     */
    private static void genericClassDemo() {
        System.out.println("=== 泛型类演示 ===");

        // 创建不同类型的容器
        Container stringContainer = new Container<>("Hello Generics");
        stringContainer.set("Hello1 Generics");
        Container intContainer = new Container<>(42);
        Container listContainer = new Container<>(Arrays.asList("a", "b", "c"));

        System.out.println("字符串容器: " + stringContainer.get());
        System.out.println("整数容器: " + intContainer.get());
        System.out.println("列表容器: " + listContainer.get());

        // 有界类型参数
        NumberContainer intNumberContainer = new NumberContainer<>(34234);
        NumberContainer<Double> doubleNumberContainer = new NumberContainer<>(3.14);

        System.out.println("整数运算: " + intNumberContainer.add(50));
        System.out.println("浮点运算: " + doubleNumberContainer.add(2.86));

        System.out.println();
    }

    /**
     * 泛型方法演示
     */
    private static void genericMethodDemo() {
        System.out.println("=== 泛型方法演示 ===");

        // 静态泛型方法
        String[] stringArray = {"apple", "banana", "cherry"};
        Integer[] intArray = {1, 2, 3, 4, 5};

        System.out.println("字符串数组: " + arrayToList(stringArray));
        System.out.println("整数数组: " + arrayToList(intArray));

        // 交换元素
        List<String> fruits = new ArrayList<>(Arrays.asList("apple", "banana"));
        System.out.println("交换前: " + fruits);
        swap(fruits, 0, 1);
        System.out.println("交换后: " + fruits);

        // 多类型参数方法
        Pair<String, Integer> pair = createPair("Java", 25);
        System.out.println("创建的对: " + pair);

        System.out.println();
    }

    /**
     * 通配符演示
     */
    private static void wildcardDemo() {
        System.out.println("=== 通配符演示 ===");

        List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5);
        List<Double> doubleList = Arrays.asList(1.1, 2.2, 3.3);
        List<Number> numberList = new ArrayList<>();

        // 上界通配符 - 只能读取
        System.out.println("整数列表和: " + sumNumbers(intList));
        System.out.println("浮点列表和: " + sumNumbers(doubleList));

        // 下界通配符 - 只能写入
        addNumbers(numberList, intList);
        System.out.println("添加后的数字列表: " + numberList);

        // 无界通配符
        printList(intList);
        printList(Arrays.asList("a", "b", "c"));

        System.out.println();
    }

    // 静态泛型方法：数组转列表
    public static <T> List<T> arrayToList(T[] array) {
        return new ArrayList<>(Arrays.asList(array));
    }

    // 多类型参数方法
    public static <T, U> Pair<T, U> createPair(T first, U second) {
        return new Pair<>(first, second);
    }

    // 上界通配符：只能读取
    public static double sumNumbers(List<? extends Number> numbers) {
        double sum = 0.0;
        for (Number num : numbers) {
            sum += num.doubleValue();
        }
        return sum;
    }

    // 下界通配符：只能写入
    public static void addNumbers(List<? super Integer> dest, List<Integer> src) {
        for (Integer num : src) {
            dest.add(num);
        }
    }

    // 无界通配符
    public static void printList(List<?> list) {
        for (Object item : list) {
            System.out.print(item + " ");
        }
        System.out.println();
    }

    /**
     * 类型擦除演示
     */
    private static void typeErasureDemo() {
        System.out.println("=== 类型擦除演示 ===");

        List<String> stringList = new ArrayList<>();
        List<Integer> intList = new ArrayList<>();

        // 运行时类型相同，都是ArrayList
        System.out.println("stringList类型: " + stringList.getClass());
        System.out.println("intList类型: " + intList.getClass());
        System.out.println("类型相同: " + (stringList.getClass() == intList.getClass()));

        // 无法在运行时获取泛型类型信息
        // System.out.println(stringList instanceof List<String>); // 编译错误
        System.out.println("只能检查原始类型: " + (stringList instanceof List));

        System.out.println();
    }

    /**
     * 泛型最佳实践
     */
    private static void bestPracticesDemo() {
        System.out.println("=== 泛型最佳实践 ===");

        // 1. 使用有意义的类型参数名
        Map<String, List<String>> categoryMap = new HashMap<>();

        // 2. 优先使用泛型而不是原始类型
        List<String> goodList = new ArrayList<>();  // 推荐
        // List badList = new ArrayList();  // 不推荐

        // 3. 使用钻石操作符简化代码（Java 7+）
        Map<String, List<Integer>> scoreMap = new HashMap<>();  // 右侧可省略类型

        // 4. 合理使用通配符
        List<? extends Number> readOnlyNumbers = Arrays.asList(1, 2.0, 3L);
        // readOnlyNumbers.add(4);  // 编译错误，不能添加

        System.out.println("最佳实践演示完成");
        System.out.println();
    }
}
/**
 * 泛型类示例
 */
class Container<T> {
    private T item;

    public Container(T item) {
        this.item = item;
    }

    public T get() {
        return item;
    }

    public void set(T item) {
        this.item = item;
    }
}
/**
 * 有界类型参数示例
 */
class NumberContainer<T extends Number> {
    private T number;

    public NumberContainer(T number) {
        this.number = number;
    }

    public double add(T other) {
        return number.doubleValue() + other.doubleValue();
    }
}

/**
 * 泛型对类
 */
class Pair<T, U> {
    private T first;
    private U second;

    public Pair(T first, U second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() { return first; }
    public U getSecond() { return second; }

    @Override
    public String toString() {
        return "(" + first + ", " + second + ")";
    }
}